﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Markup;
using System.Windows.Media;

namespace Kokomo.Controls
{
	// Derives from FrameworkElement for Style and DataContext
	[ContentProperty("DataContext")]
	public class DocumentItem : FrameworkElement
	{
		public DocumentItem()
		{
		}

		#region Events
		public static readonly RoutedEvent DocumentItemDragStartEvent = EventManager.RegisterRoutedEvent("DocumentItemDragStart", RoutingStrategy.Bubble, typeof(EventHandler<DocumentItemDragStartEventArgs>), typeof(DocumentItemDragStartEventArgs));
		#endregion

		public string Title
		{
			get { return (string)GetValue(TitleProperty); }
			set { SetValue(TitleProperty, value); }
		}

		// Using a DependencyProperty as the backing store for Title.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty TitleProperty =
			DependencyProperty.Register("Title", typeof(string), typeof(DocumentItem), new UIPropertyMetadata(OnTitleChanged));

		private static void OnTitleChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
		{
		}

		public object Item
		{
			get
			{
				object item = this.DataContext;
				return item;
				//ItemsControl itemsControl = ItemsControl.ItemsControlFromItemContainer(this);
				//object item = itemsControl.ItemContainerGenerator.ItemFromContainer(this);
				//return item;
			}
			set
			{
				this.DataContext = value;
			}
		}

		public bool IsDirty
		{
			get { return (bool)GetValue(IsDirtyProperty); }
			set { SetValue(IsDirtyProperty, value); }
		}

		// Using a DependencyProperty as the backing store for IsDirty.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty IsDirtyProperty =
			DependencyProperty.Register("IsDirty", typeof(bool), typeof(DocumentItem), new UIPropertyMetadata(false));

		public bool IsSelected
		{
			get { return (bool)GetValue(IsSelectedProperty); }
			set { SetValue(IsSelectedProperty, value); }
		}

		// Using a DependencyProperty as the backing store for IsSelected.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty IsSelectedProperty = Selector.IsSelectedProperty.AddOwner(typeof(DocumentItem), new FrameworkPropertyMetadata(false, OnIsSelectedChanged));

		private static void OnIsSelectedChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
		{
			DocumentItem item = (DocumentItem)target;

			bool isSelected = (bool)e.NewValue;
			if (isSelected)
			{
				item.OnSelected();
			}
			else
			{
				item.OnUnselected();
			}
		}

		private void OnUnselected()
		{
			this.RaiseEvent(new RoutedEventArgs(Selector.UnselectedEvent, this));
		}

		private void OnSelected()
		{
			this.RaiseEvent(new RoutedEventArgs(Selector.SelectedEvent, this));
		}

		public bool IsSelectedWithinGroup
		{
			get { return (bool)GetValue(IsSelectedWithinGroupProperty); }
			set { SetValue(IsSelectedWithinGroupProperty, value); }
		}

		// Using a DependencyProperty as the backing store for IsSelectedWithinGroup.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty IsSelectedWithinGroupProperty =
			DependencyProperty.Register("IsSelectedWithinGroup", typeof(bool), typeof(DocumentItem), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));


		public int Group
		{
			get { return (int)GetValue(GroupProperty); }
			set { SetValue(GroupProperty, value); }
		}

		// Using a DependencyProperty as the backing store for Group.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty GroupProperty =
			DependencyProperty.Register("Group", typeof(int), typeof(DocumentItem), new UIPropertyMetadata(-1, OnGroupChanged));

		private static void OnGroupChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
		{
			((DocumentItem)target).OnGroupChanged();
		}

		public event EventHandler GroupChanged;
		protected virtual void OnGroupChanged()
		{
			if (this.GroupChanged != null) this.GroupChanged(this, EventArgs.Empty);
		}

		public bool IsFloating
		{
			get { return (bool)GetValue(IsFloatingProperty); }
			set { SetValue(IsFloatingProperty, value); }
		}

		// Using a DependencyProperty as the backing store for IsFloating.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty IsFloatingProperty =
			DependencyProperty.Register("IsFloating", typeof(bool), typeof(DocumentItem), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsFloatingChanged));

		static void OnIsFloatingChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
		{
			DocumentItem item = (DocumentItem)target;
			bool isFloating = (bool)e.NewValue;
			item.IsDocked = !isFloating;
			if (isFloating)
			{

			}
			else
			{
				if (item.FloatingWindow != null)
				{

				}
			}

			item.OnIsFloatingChanged();
		}

		public event EventHandler IsFloatingChanged;
		protected virtual void OnIsFloatingChanged()
		{
			if (this.IsFloatingChanged != null) this.IsFloatingChanged(this, EventArgs.Empty);
		}

		public bool IsDocked
		{
			get { return (bool)GetValue(IsDockedProperty); }
			set { SetValue(IsDockedProperty, value); }
		}

		// Using a DependencyProperty as the backing store for IsDocked.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty IsDockedProperty =
			DependencyProperty.Register("IsDocked", typeof(bool), typeof(DocumentItem), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsDockedChanged));

		static void OnIsDockedChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
		{
			DocumentItem item = (DocumentItem)target;
			item.OnIsDockedChanged(e);
		}
		public event EventHandler IsDockedChanged;
		protected virtual void OnIsDockedChanged(DependencyPropertyChangedEventArgs e)
		{
			this.IsFloating = !(bool)e.NewValue;
			if (this.IsDockedChanged != null) this.IsDockedChanged(this, EventArgs.Empty);
			//this.InvalidateProperty(IsSelectableProperty);
		}

		void FloatingWindow_Activated(object sender, EventArgs e)
		{
			this.IsSelected = true;
		}

		void FloatingWindow_Closed(object sender, EventArgs e)
		{
			Window window = (Window)sender;
			this.RemoveLogicalChild(window.Content);
			window.Content = null;
			this.FloatingWindow = null;
			this.IsFloating = false;
		}

		private FloatingWindow _floatingWindow;
		public FloatingWindow FloatingWindow
		{
			get { return this._floatingWindow; }
			internal set
			{
				if (this._floatingWindow != null)
				{
					this._floatingWindow.Closed -= new EventHandler(FloatingWindow_Closed);
					this._floatingWindow.Activated -= new EventHandler(FloatingWindow_Activated);
				}
				this._floatingWindow = value;
				if (value != null)
				{
					value.Closed += new EventHandler(FloatingWindow_Closed);
					value.Activated += new EventHandler(FloatingWindow_Activated);
				}
			}
		}
	}
}
